#include "app.h"

FILE * newFile = NULL;

unsigned int array_to_int(char * buf)
{
  unsigned int res = 0;
  char * res_p = (char *) (&res);
  res_p[0] = buf[0];
  res_p[1] = buf[1];
  res_p[2] = buf[2];
  res_p[3] = buf[3];
  return res;
}

char * int_to_array(unsigned int integer){
  char * res_p = (char *) (&integer);
  char * res = (char *) malloc(sizeof(unsigned int));
  res[0] = res_p[0];
  res[1] = res_p[1];
  res[2] = res_p[2];
  res[3] = res_p[3];
  return res;
}

unsigned int readFirstDataFrame(char * dataFrame, unsigned int len, FileStuff * f){
	unsigned int i, j;
	f->filename = malloc(128*sizeof(char));
	unsigned int suc = 0;
	unsigned int csep = 0;
	for(i=4, j=0; i < len; i++, j++) {
		if(dataFrame[i] == SEP){ 
			csep++; j = 0;
		}else if(dataFrame[i] != SEP && csep == 0){
			f->filename[j]=dataFrame[i];
		}else if(dataFrame[i] != SEP && csep==1) {
			f->file_size = array_to_int(&(dataFrame[i]));
			suc=1;
			break;

		}
	}
	return suc;
}

unsigned int calcBCC(char * data, unsigned int size) {
	unsigned int bcc = 0;
	unsigned int i = 0;
	for(i = 0; i < size; i++) {
		bcc = bcc ^ data[i];
	}
	return bcc;
}


/*return 0 se trama invalida
  return 3 se Disc Frame(valor enum)
  return 1 se trama valida
*/
unsigned int validateFrame(char * buffer, unsigned int size, unsigned int seq) {
	unsigned int dataSize = 0;//tamanho dados stuffed

	char * data = 0;
	
	if(size < 5)
		return 0;
	
	// validate header
	if(buffer[0] != FLAG) return 0;
	if(buffer[1] != ADDR_TRANS) return 0;
	
	// DISC frame
	if(buffer[2] == CTRL_DISC) {
		if(buffer[3] != (ADDR_TRANS ^ CTRL_DISC)) return 0;
		if(buffer[4] != FLAG) return 0;
		printf("Recieved DISC.\n");
		return _DISC;
	}
	
	// Data frame
	else if((buffer[2] == CTRL_S0 && seq == 0) || (buffer[2] == CTRL_S1 && seq == 1)) {
		if(buffer[3] != (ADDR_TRANS ^ buffer[2])) return 0;
		data = destuff(buffer, 4, size - 1, &dataSize);
		unsigned int bcc = calcBCC(data, dataSize - 1);
		if(data[dataSize - 1] != bcc){return 0;}
		if(buffer[size - 1] != FLAG) return 0;
		printf("Recieved information packet.\n");		
		return 1;
	}
	else return 0;
}


unsigned int receiverMain(unsigned int fd, char * dataFrame, unsigned int seq){

	unsigned int valid = 0;
	unsigned int flag = 0;
	unsigned int i = 0; //tamanho da trama

	char c = 0;
	
	while(!valid) {
		if(flag == 1) { i = 1; dataFrame[0] = FLAG;}
		else i = 0;
		while(flag < 2) {
			read(fd, &c, 1);
			if(c == FLAG) ++flag;//se encontrar FLAG(pode ser primeira ou ultima)
			dataFrame[i++] = c;
		}
		flag = 1;
		valid = validateFrame(dataFrame, i, seq);
	}
	if(valid == _DISC) return -1;
	return i;
}
